package com.example.lt.service.user.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.lt.context.BaseContext;
import com.example.lt.entity.user.Favorites;
import com.example.lt.entity.user.FavoritesVideo;
import com.example.lt.exception.BaseException;
import com.example.lt.mapper.user.FavoritesMapper;
import com.example.lt.service.user.FavoritesService;
import com.example.lt.service.user.FavoritesVideoService;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Author 小涛Tao
 * @Date: 2024/07/28/16:38
 * version 1.0 注释：收藏夹服务类
 **/
@Service
public class FavoritesServiceImpl extends ServiceImpl<FavoritesMapper, Favorites> implements FavoritesService {

    private FavoritesVideoService favoritesVideoService;

    public FavoritesServiceImpl(FavoritesVideoService favoritesVideoService) {
        this.favoritesVideoService = favoritesVideoService;
    }

    /**
     * 判断对应的收藏夹是否存在
     * @param userId 用户id
     * @param defaultId 收藏夹id（默认的）
     */
    @Override
    public void exist(Long userId, Long defaultId) {
        final int count = count(new LambdaQueryWrapper<Favorites>()
                .eq(Favorites::getUserId, userId)
                .eq(Favorites::getId, defaultId));
        // 如果查找到的数量为0，则是不存在这个文件夹
        if (count == 0) {
            throw new BaseException("收藏夹选择错误");
        }
    }

    /**
     * 删除收藏夹
     * @param id 收藏夹id
     * @param userId 用户id
     */
    @Override
    public void remove(Long id, Long userId) {
        // 不能删除默认收藏夹
        final Favorites favorites = getOne(new LambdaQueryWrapper<Favorites>()
                .eq(Favorites::getId, id).eq(Favorites::getUserId, userId));

        if (ObjectUtils.isEmpty(favorites)) throw new BaseException("你小子还想删别人的收藏夹是吧？");

        if (favorites.getName().equals("默认收藏夹")) {
            throw new BaseException("不允许删除默认收藏夹");
        }

        final boolean result = remove(new LambdaQueryWrapper<Favorites>()
                .eq(Favorites::getId, id)
                .eq(Favorites::getUserId, userId));
        if (result) {
            // 删除收藏夹中的收藏视频记录
            favoritesVideoService.remove(new LambdaQueryWrapper<FavoritesVideo>()
                    .eq(FavoritesVideo::getFavoritesId, id));
        }
    }

    /**
     * 获取用户的所有收藏夹
     * @param userId 用户id
     * @return 返回用户的所有收藏夹，包括收藏夹下的视频总数
     */
    @Override
    public List<Favorites> listByUserId(Long userId) {
        // 查询出所有收藏夹
        final List<Favorites> favorites = list(new LambdaQueryWrapper<Favorites>().eq(Favorites::getUserId, userId));
        if (ObjectUtils.isEmpty(favorites)) return Collections.EMPTY_LIST;

        // 提取出收藏夹的id集合
        final List<Long> fIds = favorites.stream().map(Favorites::getId).collect(Collectors.toList());
        // 根据收藏夹id集合查询出所有关联的视频，并获取对应收藏夹下的视频总数
        final Map<Long, Long> fCountMap = favoritesVideoService.list(new LambdaQueryWrapper<FavoritesVideo>().in(FavoritesVideo::getFavoritesId, fIds))
                .stream().collect(Collectors.groupingBy(FavoritesVideo::getFavoritesId, Collectors.counting())); // 通过groupingBy()方法分组

        for (Favorites favorite : favorites) {
            // 获取收藏夹下对应的视频总数
            final Long videoCount = fCountMap.get(favorite.getId());
            favorite.setVideoCount(videoCount == null ? 0 : videoCount);
        }
        return favorites;
    }

    /**
     * 视频的收藏或取消收藏
     * @param favoritesId 收藏夹id
     * @param videoId 视频id
     * @return true：收藏操作   false：取消收藏操作
     */
    @Override
    public boolean favorites(Long favoritesId, Long videoId) {
        final Long userId = BaseContext.get();

        try {
            // 因为在数据库的【收藏视频表】中有【userId、favoritesId和videoId】这三个字段组成的唯一组合索引
            final FavoritesVideo favoritesVideo = FavoritesVideo.builder()
                    .userId(userId).favoritesId(favoritesId).videoId(videoId).build();
            // 所以在这里创建完实例对象就直接添加，如果没有异常就说明这次操作是【收藏操作】
            favoritesVideoService.save(favoritesVideo);

        } catch (Exception e) {
            // 如果有异常就说明这次操作是【取消收藏操作】
            favoritesVideoService.remove(new LambdaQueryWrapper<FavoritesVideo>()
                    .eq(FavoritesVideo::getUserId, userId)
                    .eq(FavoritesVideo::getFavoritesId, favoritesId)
                    .eq(FavoritesVideo::getVideoId, videoId));

            return false; // false：取消收藏操作
        }

        return true; // true：收藏操作
    }


    /**
     * 获取用户收藏夹下的视频id集合
     * @param favoriteId 收藏夹id
     * @param userId 用户id
     * @return 视频id集合
     */
    @Override
    public List<Long> listVideoIds(Long favoriteId, Long userId) {
        // userId是从token中解析出来的，是为了在这里做个【校验】，防止他人直接用【收藏夹id】获取收藏夹里面的信息
        final Favorites favorites = getOne(new LambdaQueryWrapper<Favorites>()
                .eq(Favorites::getId, favoriteId).eq(Favorites::getUserId, userId));
        if (ObjectUtils.isEmpty(favorites)) {
            throw new BaseException("该收藏夹不存在");
        }

        // 获取收藏视频中的信息，并提取出【视频id】为List集合返回
        final List<Long> videoIds = favoritesVideoService.list(new LambdaQueryWrapper<FavoritesVideo>()
                        .eq(FavoritesVideo::getFavoritesId, favoriteId))
                .stream().map(FavoritesVideo::getVideoId).collect(Collectors.toList());

        return videoIds;
    }

    /**
     * 收藏状态
     * @param videoId 视频id
     * @param userId 用户id
     * @return
     */
    @Override
    public Boolean favoritesState(Long videoId, Long userId) {
        if (userId == null) return false;
        return favoritesVideoService.count(new LambdaQueryWrapper<FavoritesVideo>().eq(FavoritesVideo::getVideoId,videoId).eq(FavoritesVideo::getUserId,userId)) == 1;
    }

}
